#include <ir/array_info.h>

namespace ir {
  bool ArrayInfo::is_in_range(int index) {
    return index >= 0 && index < (int)this->arr_size.size();
  }

  ArrayInfo::ArrayInfo(ArrayType & _arr_size)
  : arr_size(_arr_size) {}

  int ArrayInfo::depth_size_at(int index) {
    return this->arr_size.at(index);
  }

  int ArrayInfo::depth_count() {
    return this->arr_size.size();
  }

  int ArrayInfo::arr_size_at(int index) {
    if(this->arr_size.empty()) return 0;
    if(!is_in_range(index)) return 0;
    // If index is the end of array, that will return 1.
    int ret = 1;
    for(int i = index+1; i < (int)this->arr_size.size(); ++i) {
      ret *= this->arr_size.at(i);
    }
    return ret;
  }

  int ArrayInfo::all_size() {
    if(this->arr_size.empty()) return 0;
    int ret = 1;
    for(int num : this->arr_size) {
      ret *= num;
    }
    return ret;
  }

  int ArrayInfo::get_single_index(ArrayType & index_info) {
    if(index_info.size() > this->arr_size.size()) {
      Panic("index_info:%ld bigger than this:%ld",
          index_info.size(), this->arr_size.size());
    }
    int ret = 0;
    for(int i = 0; i < (int)index_info.size(); ++i) {
      ret += index_info.at(i) * arr_size_at(i);
    }
    return ret;
  }
}
